package com.base.library.manager;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.view.View;
import android.widget.ImageView;

import com.base.library.R;
import com.base.library.utils.StringUtils;
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestManager;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.target.Target;

import java.io.File;

public class GlideImageManager<T> {

    private final RequestManager requestManager;
    static final String FitCenter = "fitCenter";
    static final String CenterCrop = "centerCrop";
    private final Context mContext;
    private GlideCircleTransform avertTransform;
    private GlideCircleTransform circleTransform;
    private GlideRoundTransform roundTransform;
    private static volatile GlideImageManager instance;


    public static GlideImageManager getInstance(Context context) {
        if (instance == null) {
            synchronized (GlideImageManager.class) {
                if (instance == null) {
                    instance = new GlideImageManager(context);
                }
            }
        }
        return instance;
    }

    private GlideImageManager(Context context) {
        mContext = context;
        requestManager = Glide.with(mContext);
        circleTransform = new GlideCircleTransform(mContext, 0, Color.WHITE);
        avertTransform = new GlideCircleTransform(mContext, 0, Color.WHITE);
        roundTransform = new GlideRoundTransform(mContext, 4);
    }

    public void displayImage(T source, ImageView imageView) {
        this.displayImage(source, imageView, 0, 0);
    }

    public void displayImagePlaceAvatar(T source, ImageView imageView) {
        this.displayImagePlaceAvatar(source, imageView, R.drawable.default_circle_bg);
    }

    public void displayImagePlaceAvatar(T source, ImageView imageView, int def) {
        this.displayImage(source, imageView, def, def, avertTransform);
    }

    public void displayImageCircle(T source, ImageView imageView) {
        displayImageCircle(source, imageView, R.drawable.default_circle_bg);
    }

    public void displayImageCircle(T source, ImageView imageView, int defId) {
        requestManager
                .load(source)
                .placeholder(defId)
                .error(defId)
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .skipMemoryCache(false)
                .transform(circleTransform)
                .into(imageView);
    }

    public void displayImageRound(T source, ImageView imageView) {
        displayImageRound(source, imageView, 0, roundTransform);
    }

    public void displayImageRound(T source, ImageView imageView, int radius) {
        displayImageRound(source, imageView, 0, new GlideRoundTransform(mContext, radius));
    }

    public void displayImageRound(T source, ImageView imageView, int defId, BitmapTransformation transformation) {
        requestManager
                .load(source)
                .placeholder(defId)
                .error(defId)
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .skipMemoryCache(false)
                .transform(transformation)
                .into(imageView);
    }

    public void displayImagePlaceDefaultWithSize(T source, ImageView imageView, int w, int h) {
        this.displayImage(source, imageView, R.drawable.default_acitive_bg, R.drawable.default_acitive_bg, w, h);
    }

    public void displayImagePlaceDefault(T source, ImageView imageView) {
        this.displayImage(source, imageView, R.drawable.default_acitive_bg, R.drawable.default_acitive_bg);
    }

    public void displayImagePlace(T source, ImageView imageView, int def) {
        this.displayImage(source, imageView, def, def);
    }

    public void displayImage(T source, ImageView imageView, int placeImg) {
        this.displayImage(source, imageView, placeImg, 0);
    }

    /**
     * @param placeImg  默认占位图
     * @param errImg   错误图
     */
    public void displayImage(T source, ImageView imageView, int placeImg, int errImg) {
        requestManager
                .load(source)
                .placeholder(placeImg)
                .error(errImg)
                .crossFade()
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .skipMemoryCache(false)
//                .thumbnail(0.1f)
                .into(imageView);
    }

    public void displayImage(T source, ImageView imageView, int placeImg, int errImg, int w, int h) {
        requestManager
                .load(source)
                .placeholder(placeImg)
                .error(errImg)
                .crossFade()
                .centerCrop()
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .skipMemoryCache(false)
                .override(w, h)
                .into(imageView);
    }

    /**
     * @param placeImg  默认占位图
     * @param errImg   错误图
     */
    public void displayImage(T source, ImageView imageView, int placeImg, int errImg, BitmapTransformation transformation) {
        requestManager
                .load(source)
                .placeholder(placeImg)
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .skipMemoryCache(false)
                .error(errImg)
                .transform(transformation)
                .into(imageView);
    }

    /**
     * @param placeImg  默认占位图
     * @param errImg   错误图
     */
    public void displayAnimationImage(T source, ImageView imageView, int placeImg, int errImg) {
        requestManager
                .load(source)
                .placeholder(placeImg)
                .error(errImg)
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .skipMemoryCache(false)
                .thumbnail(0.1f)
                .crossFade() //设置淡入淡出效果，默认300ms，可以传参
                .decoder(new WebpGifDecorder())
                .into(imageView);
    }


    /**
     * Glide 会根据ImageView的大小，自动限制图片缓存和内存中的大小，当然也可以通过调用override(horizontalSize, verticalSize)限制图片的大小：
     */
    public void displayImage(T source, ImageView imageView, int placeImg, int errImg, String compressMode) {
        if (!StringUtils.isEmpty(CenterCrop) && compressMode.equals(CenterCrop)) {
            requestManager
                    .load(source)
                    .placeholder(placeImg)
                    .error(errImg)
                    .centerCrop()
                    .diskCacheStrategy(DiskCacheStrategy.ALL)
                    .skipMemoryCache(false)
                    .thumbnail(0.1f)
                    .into(imageView);
        } else if (!StringUtils.isEmpty(CenterCrop) && compressMode.equals(FitCenter)) {
            requestManager
                    .load(source)
                    .placeholder(placeImg)
                    .error(errImg)
                    .diskCacheStrategy(DiskCacheStrategy.ALL)
                    .skipMemoryCache(false)
                    .fitCenter()
                    .thumbnail(0.1f)
                    .into(imageView);
        } else {
            requestManager
                    .load(source)
                    .placeholder(placeImg)
                    .error(errImg)
                    .thumbnail(0.1f)
                    .diskCacheStrategy(DiskCacheStrategy.ALL)
                    .skipMemoryCache(false)
                    .into(imageView);
        }
    }


    /**
     * Glide 会根据ImageView的大小，自动限制图片缓存和内存中的大小，当然也可以通过调用override(horizontalSize, verticalSize)限制图片的大小：
     */
    public void displayImage(T source, ImageView imageView, int placeImg, int errImg, int horizontalSize, int verticalSize, String compressMode) {
        if (compressMode.equals(CenterCrop)) {
            requestManager
                    .load(source)
                    .placeholder(placeImg)
                    .error(errImg)
                    .override(horizontalSize, horizontalSize)
                    .centerCrop()
                    .diskCacheStrategy(DiskCacheStrategy.ALL)
                    .skipMemoryCache(false)
                    .thumbnail(0.1f)
                    .into(imageView);
        } else if (compressMode.equals(FitCenter)) {
            requestManager
                    .load(source)
                    .placeholder(placeImg)
                    .error(errImg)
                    .diskCacheStrategy(DiskCacheStrategy.ALL)
                    .skipMemoryCache(false)
                    .override(horizontalSize, horizontalSize)
                    .fitCenter()
                    .thumbnail(0.1f)
                    .into(imageView);
        } else {
            requestManager
                    .load(source)
                    .placeholder(placeImg)
                    .error(errImg)
                    .diskCacheStrategy(DiskCacheStrategy.ALL)
                    .skipMemoryCache(false)
                    .thumbnail(0.1f)
                    .override(horizontalSize, horizontalSize)
                    .into(imageView);
        }
    }


    /**
     * Glide 显示gif
     */
    public void displayGIFImage(T source, ImageView imageView, int placeImg, int errImg) {
        requestManager
                .load(source)
                .asGif()
                .placeholder(placeImg)
                .error(errImg)
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .skipMemoryCache(false)
                .fitCenter()
                .thumbnail(0.1f)
                .into(imageView);
    }


    /**
     * Glide 回调bitmap
     */
    public void displayImageCallBitmap(T source, ImageView imageView, int placeImg, int errImg) {
        requestManager
                .load(source)
                .asBitmap()
                .into(new SimpleTarget<Bitmap>() {
                    @Override
                    public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
                        imageView.setImageBitmap(resource);
                    }
                });
    }


    /**
     * Glide 回调bitmap
     */
    public void displayImageListen(T source, ImageView imageView, int placeImg, int errImg) {
        requestManager
                .load(source)
                .listener(new RequestListener<T, GlideDrawable>() {
                    @Override
                    public boolean onException(Exception e, T model, Target<GlideDrawable> target, boolean isFirstResource) {
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(GlideDrawable resource, T model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
                        return false;
                    }
                })
                .into(imageView);
    }


    /**
     * Glide 恢复加载
     */
    public void resume() {
        requestManager.resumeRequests();
    }


    /**
     * Glide 暂停加载
     */
    public void pause() {
        requestManager.pauseRequests();
    }


    /**
     * Glide 取消请求
     */
    public void clear(View view) {
        Glide.clear(view);
    }

    public void displayImageNoCache(T source, ImageView imageView, int placeImg) {
        requestManager
                .load(source)
                .placeholder(placeImg)
                .thumbnail(0.1f)
                .skipMemoryCache(true)
                .diskCacheStrategy(DiskCacheStrategy.NONE)
                .into(imageView);
    }

    public void storeImageFromService(T source) {
        requestManager
                .load(source)
                .downloadOnly(new SimpleTarget<File>() {
                    @Override
                    public void onResourceReady(File resource, GlideAnimation<? super File> glideAnimation) {

                    }
                });
    }
}
